using System;
using System.Collections.Generic;
using System.Text;

namespace Mud.Common.Physical
{

    /// <summary>
    /// Represents a location in the world.
    /// </summary>
    public struct Location
    {

        #region Properties

        public static readonly Location None = new Location(int.MaxValue, int.MaxValue);


        /// <summary>
        /// X coordinate
        /// </summary>
        public int X
        {
            get { return _x; }
            set {
                if (value < 0)
                    throw new ArgumentOutOfRangeException("Location must be positive.");

                _x = value; 
            }
        }
        private int _x;

        /// <summary>
        /// Y coordinate
        /// </summary>
        public int Y
        {
            get { return _y; }
            set {
                if (value < 0)
                    throw new ArgumentOutOfRangeException("Location must be positive.");

                _y = value; 
            }
        }
        private int _y;


        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="Location"/> class.
        /// </summary>
        /// <param name="x">The X coordinate.</param>
        /// <param name="y">The Y coordinate.</param>
        public Location(int x, int y)
        {
            if (x < 0 || y < 0)
                throw new ArgumentOutOfRangeException("Location must be positive.");
            _x = x;
            _y = y;
        }

        /// <summary>
        /// Gets a value indicating whether this instance does not represent a valid location.
        /// </summary>
        /// <value><c>true</c> if this instance is not a valid location; otherwise, <c>false</c>.</value>
        public bool IsNone 
        {
            get { return this == None; }
        }

        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator ==(Location left, Location right)
        {
            return (left.X == right.X && left.Y == right.Y);
        }
        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator !=(Location left, Location right)
        {
            return !(left == right);
        }

        /// <summary>
        /// Indicates whether this instance and a specified object are equal.
        /// </summary>
        /// <param name="obj">Another object to compare to.</param>
        /// <returns>
        /// true if obj and this instance are the same type and represent the same value; otherwise, false.
        /// </returns>
        public override bool Equals(object obj)
        {
            if (obj is Location)
            {
                return (this == (Location)obj);
            }
            return false;
        }

        /// <summary>
        /// Returns the hash code for this instance.
        /// </summary>
        /// <returns>
        /// A 32-bit signed integer that is the hash code for this instance.
        /// </returns>
        public override int GetHashCode()
        {
            return (this._x ^ this._y);
        }

        /// <summary>
        /// Returns the textual representation of this instance.
        /// </summary>
        public override string ToString()
        {
            return "{X=" + _x.ToString() + ", Y=" + _y.ToString() + "}";
        }
    }
}
